package thoven.achievement.net.jsonutil.service

import java.net.URLDecoder
import java.util.Base64
import java.nio.charset.StandardCharsets

/**
 * JSON 清理和修复服务
 * 用于处理混乱的 JSON 字符串
 */
object JsonCleaner {
    
    /**
     * 清理并修复 JSON 字符串
     */
    fun clean(input: String): Result<String> {
        return try {
            var json = input.trim()
            
            // 1. 移除可能的 BOM 标记
            json = removeBOM(json)
            
            // 2. 尝试解析转义的 JSON
            json = unescapeJson(json)
            
            // 3. 尝试 URL 解码
            json = tryUrlDecode(json)
            
            // 4. 尝试 Base64 解码
            json = tryBase64Decode(json)
            
            // 5. 移除前后的垃圾字符
            json = removeGarbage(json)
            
            // 6. 修复常见的 JSON 错误
            json = fixCommonErrors(json)
            
            Result.success(json)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 解除 JSON 字符串的转义
     */
    fun unescapeJson(json: String): String {
        var result = json.trim()
        
        // 检测是否是被引号包裹的转义 JSON
        if ((result.startsWith("\"") && result.endsWith("\"")) ||
            (result.startsWith("'") && result.endsWith("'"))) {
            
            // 移除外层引号
            result = result.substring(1, result.length - 1)
            
            // 递归解转义，直到不再是转义字符串
            var previous = ""
            while (result != previous && result.contains("\\")) {
                previous = result
                result = result
                    .replace("\\\"", "\"")
                    .replace("\\\\", "\\")
                    .replace("\\/", "/")
                    .replace("\\n", "\n")
                    .replace("\\r", "\r")
                    .replace("\\t", "\t")
                    .replace("\\b", "\b")
                    .replace("\\f", "\u000C")
            }
        }
        
        return result
    }
    
    /**
     * 转义 JSON 字符串（用于日志等场景）
     */
    fun escapeJson(json: String): String {
        return json
            .replace("\\", "\\\\")
            .replace("\"", "\\\"")
            .replace("\n", "\\n")
            .replace("\r", "\\r")
            .replace("\t", "\\t")
            .replace("\b", "\\b")
            .replace("\u000C", "\\f")
            .let { "\"$it\"" }
    }
    
    /**
     * 移除 BOM 标记
     */
    private fun removeBOM(json: String): String {
        return if (json.isNotEmpty() && json[0] == '\uFEFF') {
            json.substring(1)
        } else {
            json
        }
    }
    
    /**
     * 尝试 URL 解码
     */
    private fun tryUrlDecode(json: String): String {
        return try {
            if (json.contains("%7B") || json.contains("%22") || json.contains("%3A")) {
                URLDecoder.decode(json, StandardCharsets.UTF_8.name())
            } else {
                json
            }
        } catch (e: Exception) {
            json
        }
    }
    
    /**
     * 尝试 Base64 解码
     */
    private fun tryBase64Decode(json: String): String {
        return try {
            // 简单检测是否可能是 Base64
            if (!json.trim().startsWith("{") && 
                !json.trim().startsWith("[") &&
                json.matches(Regex("^[A-Za-z0-9+/=]+$"))) {
                
                val decoded = Base64.getDecoder().decode(json)
                val decodedStr = String(decoded, StandardCharsets.UTF_8)
                
                // 验证解码后是否像 JSON
                if (decodedStr.trim().startsWith("{") || decodedStr.trim().startsWith("[")) {
                    return decodedStr
                }
            }
            json
        } catch (e: Exception) {
            json
        }
    }
    
    /**
     * 移除前后的垃圾字符
     */
    private fun removeGarbage(json: String): String {
        var result = json.trim()
        
        // 找到第一个 { 或 [
        val startIndex = result.indexOfFirst { it == '{' || it == '[' }
        if (startIndex > 0) {
            result = result.substring(startIndex)
        }
        
        // 找到最后一个 } 或 ]
        val endIndex = result.indexOfLast { it == '}' || it == ']' }
        if (endIndex >= 0 && endIndex < result.length - 1) {
            result = result.substring(0, endIndex + 1)
        }
        
        return result
    }
    
    /**
     * 修复常见的 JSON 错误
     */
    private fun fixCommonErrors(json: String): String {
        var result = json
        
        // 1. 替换单引号为双引号（简单处理）
        result = fixSingleQuotes(result)
        
        // 2. 移除尾部逗号
        result = removeTrailingCommas(result)
        
        // 3. 移除注释
        result = removeComments(result)
        
        return result
    }
    
    /**
     * 修复单引号（简化版本，适用于简单场景）
     */
    private fun fixSingleQuotes(json: String): String {
        // 这是一个简化实现，只处理简单的单引号替换
        var result = json
        var inString = false
        var stringChar = ' '
        val sb = StringBuilder()
        
        var i = 0
        while (i < result.length) {
            val c = result[i]
            
            when {
                !inString && (c == '"' || c == '\'') -> {
                    inString = true
                    stringChar = c
                    sb.append('"') // 统一使用双引号
                }
                inString && c == stringChar -> {
                    // 检查是否是转义的引号
                    if (i > 0 && result[i - 1] == '\\') {
                        sb.append(c)
                    } else {
                        inString = false
                        sb.append('"') // 统一使用双引号
                    }
                }
                else -> {
                    sb.append(c)
                }
            }
            i++
        }
        
        return sb.toString()
    }
    
    /**
     * 移除尾部逗号
     */
    private fun removeTrailingCommas(json: String): String {
        return json
            .replace(Regex(",\\s*}"), "}")
            .replace(Regex(",\\s*]"), "]")
    }
    
    /**
     * 移除注释（// 和 /* ... */）
     */
    private fun removeComments(json: String): String {
        var result = json
        
        // 移除单行注释
        result = result.replace(Regex("//.*?(?=\n|$)"), "")
        
        // 移除多行注释
        result = result.replace(Regex("/\\*.*?\\*/", RegexOption.DOT_MATCHES_ALL), "")
        
        return result
    }
}

